package org.vijay.core.jwt;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.jose4j.jws.AlgorithmIdentifiers;
import org.jose4j.jws.JsonWebSignature;
import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.NumericDate;
import org.jose4j.lang.JoseException;

import java.security.*;
import java.security.spec.InvalidKeySpecException;

public class JWTMain {
    private static final String publicKeyStr = "BBYCxwATP2vVgw7mMPHJfT6bZrJP2iUV7OP_oxHzEcNFenrX66D8G34CdEmVULNg4WJXfjkeyT0AT9LwavpN8M4=";
    private static final String privateKeyStr = "AKYLHgp-aV3kOys9Oy6QgxNI6OGIlOB3G6kjGvhl57j_";

    private static PublicKey publicKey;
    private static Key privateKey;

    static {

        try {
            tryLoadProvider();
            publicKey = Utils.loadPublicKey(publicKeyStr);
            privateKey = Utils.loadPrivateKey(privateKeyStr);
        } catch (NoSuchProviderException | NoSuchAlgorithmException | InvalidKeySpecException e) {
            e.printStackTrace();
        }

    }

    public synchronized static void tryLoadProvider() {
        // Add BouncyCastle as an algorithm provider
        if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
            Security.addProvider(new BouncyCastleProvider());
        }
    }

    public static void main(String[] args) throws Exception {

        String cs = compactSerialization();

        if(cs==null||cs.length()==0){
            return;
        }
        JsonWebSignature jws=new JsonWebSignature();
        //Header  {Authorization:jwt}
        jws.setCompactSerialization(cs);
        jws.setKey(publicKey);
        //验签
        boolean vRet = jws.verifySignature();
        if(vRet){
            System.out.println(vRet);
            //payload
            String payload = jws.getPayload();
            JwtClaims jwtClaims = JwtClaims.parse(payload);
            System.out.println(jwtClaims);

        }
    }

    /**
     * header:payload:signature
     * @return
     */
    public static String compactSerialization() {
        String origin = "http://127.0.0.1";
        String subject = "";
        JwtClaims claims = new JwtClaims();
        claims.setAudience(origin);
        claims.setExpirationTimeMinutesInTheFuture(12 * 60);
        claims.setSubject(subject);
        JsonWebSignature jws = new JsonWebSignature();
        jws.setHeader("typ", "JWT");
        jws.setHeader("alg", "ES256");
        jws.setPayload(claims.toJson());
        jws.setKey(privateKey);
        jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.ECDSA_USING_P256_CURVE_AND_SHA256);
        try {
            return jws.getCompactSerialization();
        } catch (JoseException e) {
            return "";
        }
    }

    public String jwtWithHs256(String sub, String[] aud, String jid) throws JoseException {
        JsonWebSignature jws = new JsonWebSignature();
        //设置Header
        jws.setHeader("alg","HS256");
        jws.setHeader("typ","JWT");
        jws.setHeader("kid","ABCDEFG");
        //设置PayLoad
        JwtClaims jwtClaims = new JwtClaims();
        jwtClaims.setIssuer("me");
        jwtClaims.setSubject(sub);
        jwtClaims.setAudience(aud);
        jwtClaims.setExpirationTime(NumericDate.fromSeconds(2 * 60 * 60));
        jwtClaims.setNotBefore(NumericDate.now());
        jwtClaims.setIssuedAt(NumericDate.now());
        jwtClaims.setJwtId(jid);
        jws.setPayload(jwtClaims.toJson());
        //设置签名key:最小长度为256位
        //jws.setKey(new HmacKey(SECRET.getBytes()));
        return jws.getCompactSerialization();
    }

}
